<?php

    #-------------------------------------------------------------#
	# This file is part of the Tekuna MVC Microframework for PHP. #
	# (c) 2009 Niels Jäckel <niels.jaeckel@tekuna.org>            #
	# Please visit http://tekuna.org/ for more information.       #
	#                                                             #
	# This software is licensed under the MIT License. Please     #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#


	Tekuna :: load('org.tekuna.core.config.ApplicationConfigurationBuilder');


	class ApplicationConfigBuilderTest extends AbstractTekunaTestCase {


		public function testNonExistentConfig() {

			// test non-existent configuration file
			try {

				$objConfig = ApplicationConfigurationBuilder :: buildConfigurationFromXMLFile('nonExistentConfigurationFile.xml');
				$this -> fail();
			}
			catch (TekunaApplicationException $e) {

				$this -> pass();
			}
		}


		public function testValidConfig() {

			// load valid config file
			$objConfig = ApplicationConfigurationBuilder :: buildConfigurationFromXMLFile(APPLICATION_ROOT . 'testConfigs/validApplicationConfig.xml');

			// test config
			$this -> assertIdentical(count($objConfig -> getAllModules()), 2);
			$this -> assertIdentical($objConfig -> getModuleForURL('/test/') -> getLayout(), 'test.tpl');
			$this -> assertIdentical($objConfig -> getModuleForURL('/test2/') -> getLayout(), 'test2.tpl');

			// test non-existent base URL
			try {

				$objConfig -> getModuleForURL('/nonExistingBaseURL/');
				$this -> fail();
			}
			catch (NoModuleRoutableException $e) {

				$this -> pass();
			}

			// test languages
			$this -> assertIdentical($objConfig -> getLanguages(), array('en', 'de'));

			// test module
			$objModule = $objConfig -> getModuleForURL('/test2/');

			$this -> assertIdentical($objModule -> getBaseURL(), '/test2/');
			$this -> assertIdentical($objModule -> getLayout(), 'test2.tpl');
			$this -> assertTrue($objModule -> hasStatus());
			$this -> assertIdentical($objModule -> getStatus(), 100);

			// test components
			$arrComponents = $objModule -> getAllComponents();

			// test component counts
			$this -> assertIdentical(count($arrComponents), 3);

			// test first component
			$this -> assertIdentical($arrComponents[0] -> getSlot(), 'header1');
			$this -> assertTrue($arrComponents[0] -> hasFragment());
			$this -> assertFalse($arrComponents[0] -> hasController());
			$this -> assertFalse($arrComponents[0] -> hasRoutes());
			$this -> assertIdentical($arrComponents[0] -> getFragment(), 'header');
			$this -> assertTrue($arrComponents[0] -> hasStatus());
			$this -> assertIdentical($arrComponents[0] -> getStatus(), 200);

			// test second component
			$this -> assertIdentical($arrComponents[1] -> getSlot(), 'body1');
			$this -> assertFalse($arrComponents[1] -> hasFragment());
			$this -> assertTrue($arrComponents[1] -> hasController());
			$this -> assertFalse($arrComponents[1] -> hasRoutes());
			$this -> assertIdentical($arrComponents[1] -> getController(), 'TestController');
			$this -> assertFalse($arrComponents[1] -> hasStatus());

			// test third component
			$this -> assertIdentical($arrComponents[2] -> getSlot(), 'content1');
			$this -> assertFalse($arrComponents[2] -> hasFragment());
			$this -> assertFalse($arrComponents[2] -> hasController());
			$this -> assertFalse($arrComponents[2] -> hasStatus());
			$this -> assertTrue($arrComponents[2] -> hasRoutes());

			// get routes
			$arrRoutes = $arrComponents[2] -> getAllRoutes();

			// check routes
			$this -> assertIdentical(count($arrRoutes), 5);
			$this -> assertIdentical($arrRoutes[0] -> getPattern(), 'foo.html');
			$this -> assertIdentical($arrRoutes[0] -> getFragment(), 'foo.html');
			$this -> assertIdentical($arrRoutes[0] -> getStatus(), 202);

			$this -> assertIdentical($arrRoutes[1] -> getPattern(), '*.pdf');
			$this -> assertIdentical($arrRoutes[1] -> getController(), 'PDFCreator');

			$this -> assertIdentical($arrRoutes[2] -> getPattern(), 'gallery/**/*.html');
			$this -> assertIdentical($arrRoutes[2] -> getController(), 'GalleryController');
			$this -> assertIdentical($arrRoutes[2] -> getStatus(), 204);

			$this -> assertIdentical($arrRoutes[3] -> getPattern(), '');
			$this -> assertIdentical($arrRoutes[3] -> getController(), 'DirectoryLister');
			$this -> assertIdentical($arrRoutes[3] -> getStatus(), 300);

			$this -> assertIdentical($arrRoutes[4] -> getPattern(), '*');
			$this -> assertIdentical($arrRoutes[4] -> getFragment(), '404.html');
			$this -> assertIdentical($arrRoutes[4] -> getStatus(), 404);
		}


		public function testInvalidConfigs() {

			// list invalid files
			$arrInvalidFiles = array('noLanguagesConfig1.xml',
			                         'noLanguagesConfig2.xml',
			                         'noModulesConfig.xml',
			                         'noLayoutConfig.xml',
			                         'noBaseURLConfig.xml',
			                         'noSlotConfig.xml',
			                         'noControllerConfig.xml',
			                         'noRoutePatternConfig.xml',
			                         'noRouteControllerConfig.xml',
			                         'controllerAndFragmentConfig.xml',
			                         'controllerAndFragmentAndRoutesConfig.xml',
			                         'controllerAndFragmentInRouteConfig.xml');


			// check all files
			foreach ($arrInvalidFiles as $sFile) {

				$this -> ensureInvalidConfiguration($sFile);
			}
		}


		protected function ensureInvalidConfiguration($sFileName) {

			try {

				// build full file path
				$sFilePath = APPLICATION_ROOT . 'testConfigs'. DIRECTORY_SEPARATOR . $sFileName;

				// try to load the file
				$objConfig = ApplicationConfigurationBuilder :: buildConfigurationFromXMLFile($sFilePath);

				// do not reach this statement
				$this -> fail("Configuration file '$sFileName' is spuriously regarded as valid.");
			}
			catch (ApplicationXMLParseException $e) {

				// everything OK
				$this -> pass();
			}
		}
	}



